Como esta sua situacao financeira? Caso tenha alguma reserva pode ser interessante pensar em investimentos pois a poupança já não é mais garantia de lucro no longo prazo, não acredita?
Já estamos no início de 2020 e desde 2019 já se liam notícias como esta abaixo que levam à reflexão sobre reeducação financeira pois alertam a sobre a necessidade de procurar novas oportunidades de investimento.
Com a finalidade de fomentar um pouco a discussão sobre investimentos, trouxe nesse post algumas sugestões e idéias de como elaborar uma carteira e otimizar as escolhas para equilibrar risco em novos investimentos combinando elementos de estatística, machine learning e programação em R.
Ao final do post criaremos um robo no telegram que coletará os dados das cotações adquiridas, aplicará o modelo Prophet do Facebook para forecast e analisará a desmontagem da carteira segundo os critérios estabelecidos e enviará mensagens para nós com uma tabela financeira automatizada via telegram como mostra na animação:
AVISO: Este post não tem como finalidade ser um guia de investimentos (Já existem muitas consultorias especializadas nisso por ai). Todos as decisões tomadas como diversificação da carteira, seleção de ações e critérios para desmontagem da carteira são exemplos e servem para ilustrar algumas possibilidades que um cientista de dados têm na hora de desenvolver ferramentas para auxiliar à tomada de decisão.
De acordo com um especialista entrevistado pela InfoMoney:
“Poupar é guardar dinheiro para usar no futuro, comprar alguma coisa com ele. Investimento é juntar dinheiro, não mexer nele, para que este gere rendimentos e aí sim, usar os lucros mais para frente. É o recomendado para quem quer viver de renda no futuro, por exemplo” (…)InfoMoney - Ago 2015
Ou seja, poupar é acumular agora para utilizar depois, e normalmente envolve mudança de hábitos, pois requer uma redução nos gastos pessoais e familiares, já Investir é usar esse dinheiro poupado em aplicações que rendam.
Como todo mundo sabe, não existe investimento sem risco e este risco deve ser controlado e utilizado a nosso favor de forma que gere alguma segurança financeira.
Provamente você já ouviu essa frase alguma vez na vida e ela certamente faz sentido. Não colocar todos os ovos na mesma cesta significa que você deve diversificar o seu investimento.
Diversificar a carteira irá proteger seus investimentos diminuindo o risco pois, imagine só, você investe todo o seu dinheiro em uma empresa e ela passa por alguma crise assim seu dinheiro estará todo comprometido!
Existem diversos motivos para se diversificar a carteira mas acho que essa metáfora dos ovos já resume bem.
Dependendo do risco que você deseja se expor existem muitas formas de preparar a carteira mas a idéias principal consiste em atingir um equilíbrio entre dois tipos de investimento:
Para ajudar a dividir a carteira de investimentos neste post utilizaremos a chamada Regra (ou Lei) dos 80. A estratégia é a seguinte: subtraia da sua idade o número 80. O resultado dessa conta vai indicar o percentual a ser investido em renda variável. Por exemplo, no meu caso: tenho 26 anos, portanto \(80-26 = 54\%\) deverá ser investido em renda variável. Aos 53 anos esse percentual vai cairá para a metade, \(27\%\).
A idéias principal por trás desta regra que é que a cada ano que passa, 1% do montante da renda variável deva ser direcionado para a renda fixa.
Para testar diferentes valores seguindo esta regra desenvolvi uma função que se chama montagem80() (que já está disponível no github TODO). Vejamos alguns resultaodos para diferentes cenários e vamos selecionar um para seguir com a montagem da carteira:
source("montagem80.R")
1. Entrada de R$20.000,00
montagem80(entrada = 20000, idade = 26)
## • Entrada: R$R$20.000,00
## └─ Renda fixa: R$9.200,00
## └─ Renda variavel: R$10.800,00
## (Acao + Cryptomoeda):
## R$9.720,00 + R$1.080,00
montagem80(variavel = 10800, idade = 53)
## • Entrada: R$R$40.000,00
## └─ Renda fixa: R$29.200,00
## └─ Renda variavel: R$10.800,00
## (Acao + Cryptomoeda):
## R$9.720,00 + R$1.080,00
Utilizaremos a primeira (1.) que esta assinalada em vermelho como exemplo, onde:
Após definir a quantidade a ser investida é hora de planejar a próxima estapa: a divessificação.
A diversificação é uma técnica para gestão do risco que visa distribuir o capital investido em uma variedade de investimentos dentro de da nossa carteira.
Assim, o risco do portfólio é consideravelmente reduzido pois reduzimos a volatividade e criamos um equilibrio onde um desempenho positivo de um ativo neutraliza as baixas ocorridas em outras aplicacoes. Além disso a diversificação pode ser tanto coma renda variável quanto com a renda fixa.
Mas lembre-se, não existe uma receita mais eficiente!
Normalmente diversificamos nossa renda fixa também mas como gostaria de focar nas análises de renda variável utilizaremos o simulador disponivel no site https://verios.com.br/ neste link para avaliar nossa escolha:
A título de exemplo, escolhi o Tesouro Prefixado 2015 (LTN), note que com essa escolha o lucro planejado seria de quase 3 mil reais nos próximos 5 anos.
Volto a lembrar que esta seleção é apenas um exemplo e existem diversas informações a serem levadas em conta ao se fazer esta escolha. Convido o leitor a procurar saber mais sobre os tipos, prós e contras do Tesouro Direto.
Para compor ajudar a compor a parte da cateira que de renda variável selecionei duas ações (de forma totalmente arbitrária para exemplificar neste post) que são inversamente correlacionadas baseado no excelente post "Estudo de correlação entre ações da Bolsa de Valores de São Paulo" escrito por Victor Gomes onde o autor faz um estudo de correlações das séries históricas de ações de diferentes setores.
O Bitcoin foi selecionado para completar a carteira de renda variável como um ativo de alto risco com bastante volatividade, mas por que assumir este risco?
São muitas as histórias de pessoas que ficaram milhorárias com o bitcoin pela sua valorização inesperada ao longo do tempo, como por exemplo o adolescente que ficou milionário aos 18 anos usando bitcoins após fazer aposta com os pais.
Então eu acho que 10% dessa nossa carteira (não esqueça que podemos ter mais de uma carteira) é um risco que pode valer a pena correr e por isso vou incluí-lo.
Portanto, para este exemplo consideramos:
# portifolio = c("PETR4.SA","FIBR3.SA", "BTC-USD")
portifolio = c("TUPY3.SA","ELET3.SA", "BTC-USD")
AVISO: Volto a frisar que as escolhas das ações foram feitas de forma arbitrária. Estamos em tempos de incerteza atualmente por conta do corona virus (espero que todos fiquem bem) o que leva algumas escolhas à serem ainda mais complexas e imprevisíveis.
A aquisição das série históricas das cotações destes ativoes desde 01/01/2016 foram obtidas utilizando o pacote tidyquant que nos retorna os dados das cotações das ações informadas em formato “arrumado” (ou seja, familiar com funções do tidyverse), veja:
library(tidyquant) # aquisicao de dados financeiros
# stocks <-map_df(portifolio, ~tq_get(.x, get = "stock.prices", from = " 2016-01-01"))
# saveRDS(stocks, "stocks.rds")
stocks <- readRDS("stocks.rds")
Veja as linhas iniciais do dataset obtido:
# https://github.com/gomesfellipe/functions/blob/master/inicio_e_fim_da_base.R
stocks %>% inicio_e_fim_da_base() %>% kable2()
| symbol | date | open | high | low | close | volume | adjusted |
|---|---|---|---|---|---|---|---|
| TUPY3.SA | 2016-01-04 | 18.549999 | 19.370001 | 18.379999 | 19.139999 | 300200 | 15.297645 |
| TUPY3.SA | 2016-01-05 | 19.59 | 19.59 | 17.82 | 18 | 273600 | 14.386499 |
| TUPY3.SA | 2016-01-06 | 17.700001 | 18.440001 | 17.700001 | 18.299999 | 203900 | 14.626276 |
| TUPY3.SA | 2016-01-07 | 18.1 | 18.49 | 18.01 | 18.290001 | 362100 | 14.618282 |
| TUPY3.SA | 2016-01-08 | 18.4 | 18.65 | 18.15 | 18.4 | 121100 | 14.706201 |
| TUPY3.SA | 2016-01-11 | 18.299999 | 18.59 | 17.719999 | 17.75 | 182000 | 14.186687 |
| … | … | … | … | … | … | … | … |
| BTC-USD | 2020-03-13 | 5017.831055 | 5838.114746 | 4106.980957 | 5563.707031 | 74156772074 | 5563.707031 |
| BTC-USD | 2020-03-14 | 5573.077637 | 5625.226563 | 5125.069336 | 5200.366211 | 36154506007 | 5200.366211 |
| BTC-USD | 2020-03-15 | 5201.066895 | 5836.64502 | 5169.283203 | 5392.314941 | 33997889638 | 5392.314941 |
| BTC-USD | 2020-03-16 | 5385.229492 | 5385.229492 | 4575.35791 | 5014.47998 | 45368026429 | 5014.47998 |
| BTC-USD | 2020-03-17 | 5002.578125 | 5371.348633 | 4981.90918 | 5225.629395 | 38622642935 | 5225.629395 |
| BTC-USD | 2020-03-18 | NA | NA | NA | NA | NA | NA |
Existem uma série de vantagens de se trabalhar com os dados neste formato em R, veremos o porque nas próximas seções.
O formato tsibble é um formato moderno para se trabalhar com séries temporais trazendo a filosofia do tidyverse para os dados de séries temporais facilitando o fluxo de trabalho.
Diversos outros pacotes podem ser combinados utilizando os dados no formato do pacote tsibble como os pacotes fable e o prophet (sugiro a leitura para quem nao conhece) para aplicação de modelagem de séries temporiais.
Veja como é o fluxo ao trabalhar com objetos do tipo tsibble
library(tsibble) # series temporais arrumadas
tbl_stocks <- stocks %>% as_tsibble(key = symbol, index = date, interval="Date")
Após converter para tsibble, vamos preencher alguns gaps da bolsa como por exemplo os finais de semana (quando a bolsa de valores fica fechada) com o mesmo valor do dia anterior:
tbl_stocks <-
tbl_stocks %>%
fill_gaps() %>%
tidyr::fill(c(open, high, low, close, volume, adjusted),.direction = "down")
Com os dados arrumados vamos a algumas visualizações.
Vejamos qual foi o comportamento das séries históricas que coletamos desde o início de 2016:
library(forecast) # series temporais
library(fpp3) # series temporais
d2 <-
tbl_stocks %>%
group_by(symbol) %>%
summarise(y = mean(close))
autoplot(tbl_stocks)+
geom_line(aes(group = symbol), color = "black", show.legend = F) +
facet_wrap(~symbol, scales = "free_y", ncol = 1)+
geom_ma(n=6*30, color = "red") +
theme(legend.position = "none")+
labs(subtitle = "média móvel n = 6 meses")
A série do Bitcoin é a mais imprevisível, houve um pico em 2018 mas após isso não houve nenhum grande pico como aquele. Em breve ocorrerá o Halving (a contagem regressiva pode acompanhada neste link) que é um processo de choque de oferta e ocorre aproximadamente a cada 4 anos e pode ser uma boa oportunidade de retorno.
As duas séries da bolsa de valores não parecem ter uma corerlação muito forte, os picos ocorrem de forma alternada e isto pode ser uma caracteristica boa para a carteira pois caso uma delas entre em crise a outra poderá estar em uma fase boa.
Nota: Esta queda abrupta que ocorreu na bolsa no início de 2020 é o reflexo da Pandemia CODVID-19 que já começou a apresentar alguns casos e isso certamente esta gerando muita incerteza na bolsa de valores. Nem eu nem ninguém sabe o que pode acontecer, estou na torcida para que todos fiquem bem e pelo sucesso na contenção desse virus!
AVISO: Volto a frisar que as escolhas das ações foram feitas de forma arbitrária. Estamos em tempos de incerteza atualmente por conta do corona virus (espero que todos fiquem bem) o que leva algumas escolhas à serem ainda mais complexas e imprevisíveis.
Para confirmar as conjecturas formdaas ao observar o comportamento das séries histórias (de que os picos e vales se alternam) vamos dar uma olhada nos gráficos de dispersão e coeficientes de correlação de Spearman:
points_loess <- function(data, mapping){
ggplot(data = data, mapping = mapping) +
geom_point(alpha = 0.3,size=0.5) +
geom_smooth(method = "loess")
}
tbl_stocks %>%
as_tibble() %>%
select(symbol, date, close) %>%
spread(key = symbol, value = close) %>%
GGally::ggpairs(columns = 2:4,
upper = list(continuous = GGally::wrap("cor", method = "spearman")),
lower = list(continuous = points_loess))
Note que a relação entre TUPY3 e ELET3 não é linear e além disso a correlação entre é fraca, o que pode ser benéfico para o portifólio pois uma possível queda em uma não parece não ter tanto impacto na outra.
Além disso note que a correlação do BTC-USD com TUPY3 e ELET3 é moderada e mesmo apresentando este valores numéricos, o bitcoin é um ativo negociado em escala global e é de um setor totalmente diferente das outras ações,
AVISO: Correlação não implica causalidade. Isto que dizer que poda haver uma causa em comum para ambas ou que seja uma correlação espúria
Poderíamos utilizar uma série de modelos estatísticos, econométricos e de machine learning utilizando tanto as funções nativas do R base ou pacote forecast quanto as funções desenvolvidas para trabalhar de maneira “arrumada” com tsibble mas resolvi fazer uma abordagem diferente neste post escolhendo o modelo disponibilizado pelo Facebook.
O Prophet é um software de código aberto disponibilizado pela equipe de Data Science do Facebook que fornece um procedimento para realização de previsões de dados de séries temporais.
Segundo a documentação oficial, (em tradução livre):
O prophet tem como “base em um modelo aditivo no qual tendências não lineares se ajustam à sazonalidade anual, semanal e diária, além de efeitos de férias. Funciona melhor com séries temporais que têm fortes efeitos sazonais e várias temporadas de dados históricos. O Profeta é robusto para a falta de dados e mudanças na tendência, e geralmente lida bem com outliers”.
Este modelo me pareceu uma boa opção para exemplificar a etapa da modelagem de séries temporais deste post. Vamos ver o que o modelo do Facebook tem a nos dizer sobre o futuro das nossas ações.
ASsim como em uma tarefa de machine learning que não envolvem dados temporais, no caso de séries temporais, quando desejamos avaliar o ajuste do nosso modelo também dividimos o dataset em treino e teste porém utilizamos a data como índice.
Veja como serão divididas nossas séries históricas:
h = 30 * 2
data_split <- Sys.Date() - h
tbl_stocks_train <-
tbl_stocks %>%
filter(date <= data_split) %>%
select(symbol, date, close)
tbl_stocks_test <-
tbl_stocks %>%
filter(date > data_split) %>%
select(symbol, date, close)
Após dividir os dados em treino e teste já estamos habilitados à utilizar o modelo. Note que, por default, o modelo espera duas colunas nomeadas como ds: data da série e y: variável target da série.
Além disso faremos uma previsão 6 meses a frente dos dados de teste para entender qual a tendência o modelo estaria adotando.
library(prophet)
library(patchwork)
prophet_results <-
tbl_stocks_train %>%
rename(ds = date, y = close) %>%
nest(data = c(ds, y)) %>%
mutate(pmodel = map(data, ~ prophet(.x, daily.seasonality=TRUE))
)%>%
mutate(pprediction = map(pmodel, ~.x %>%
make_future_dataframe(periods = h + 30*6) %>%
predict(.x,.)))
Veja os resultados do ajuste do modelo:
pmap(list(
x = prophet_results$pprediction,
y = split(tbl_stocks_train, tbl_stocks_train$symbol),
z = split(tbl_stocks_test, tbl_stocks_test$symbol),
w = prophet_results$symbol
),function(x, y, z, w){
x %>%
as_tibble() %>%
mutate(ds=as_date(ds)) %>%
select(ds, trend, yhat, yhat_lower, yhat_upper) %>%
ggplot() +
geom_line(aes(x=ds, y=yhat, color="blue"), show.legend = F) +
geom_line(data=y, aes(x=date, y=close, color="black"), show.legend = F) +
geom_line(data=z, aes(x=date, y=close, color="red"), show.legend = T) +
geom_ribbon(aes(x=ds, ymin=yhat_lower, ymax=yhat_upper), alpha=0.2) +
scale_x_date(#limits = c(as.Date("2018-06-01"), Sys.Date() + 30*12),
date_breaks = "6 month", date_labels = "%m/%Y") +
theme_bw()+
labs(y = w, x = "")+
scale_colour_manual(values=c("black","blue","red"), name="", labels=c("treino","modelo","teste"))+
theme(legend.position = c(1-0.8,1-0.2),
legend.background = element_rect(fill=alpha('lightgrey', 0.2)),
legend.direction = "horizontal")
}
) %>% {.[[1]] / .[[2]] / .[[3]]}
Parece interessante..
Veja que a linha azul (modelo ajustado) se ajusta bem à linha preta (dados de treino) acompanhando a série histórica e captando algumas tendências não lineares.
Porém note que a linha azul se perde completamente da linha vermelha (dados de teste) no início de 2020 e acho isso muito razoável pois dificilmente algum modelo iría prever os efeitos de uma Pandemia utilizando apenas a série histórica do ativo.
Note ainda que a linha azul se estende até o final de 2020 (previsões para os próximos 6 meses) o que sugere que a série possuía esta tendendia positiva ao longo dos anos, segundo o modelo Prophet
Aviso: Existem várias maneiras de estudar e melhorar a qualidade do ajuste deste modelo mas como o objetivo deste post não é este deixo como aviso para o leitor.
Feita a interpretação dos resultados.. vamos às compras!
Após toda essa exemplicação de como podem ser feitas as análises para a elaboracao da carteira chegou a hora das compras.
Suponha que tivessemos realizado nossas compra no fechamento do dia 09/01/2020, quando os valores de fechamento das cotações eram as seguintes:
tbl_stocks %>%
filter(date == "2020-01-09") %>%
mutate(close = cell_spec(moeda_real(close), "html", color = "blue", bold = T)) %>%
mutate_at(c(3:5, 8), ~moeda_real(.x)) %>%
kable2()
| symbol | date | open | high | low | close | volume | adjusted |
|---|---|---|---|---|---|---|---|
| BTC-USD | 2020-01-09 | R$8.082,30 | R$8.082,30 | R$7.842,40 | R$7.879,07 | 24045990465 | R$7.879,07 |
| ELET3.SA | 2020-01-09 | R$ 39,31 | R$ 39,72 | R$ 39,08 | R$ 39,35 | 4357400 | R$ 39,35 |
| TUPY3.SA | 2020-01-09 | R$ 25,84 | R$ 26,05 | R$ 25,60 | R$ 26,05 | 465400 | R$ 26,05 |
Neste dia a cotação para ELET3 era R$39,35 e TUPY3 era R$26,05 e suponha que tenhamos comprado 190 lotes fracionarios de ELET3 e 90 de TUPY, totalizando R$9.821,00 (próximo ao que avíamos planejado no inicio do estudo)
Vamos guardar estes valores:
cot_inicio = c(elet = 39.35, tupy = 26.05)
qtd_inicio = c(elet = 190, tupy = 90)
Note que o valor do Bitcoin está em dólares, para obter o valor em reais (R$) daquele dia vamos utilizar a API do Mercado Bitcoin. Como não existe nenhum pacote que forneça estes dados diretamente no R, a requisição será feita normalmente via API com o pacote jsonlite:
library(jsonlite) # requisicao de api
url <- glue::glue("https://www.mercadobitcoin.net/api/BTC/day-summary/2020/01/09/")
safe_fromJSON <- safely(fromJSON, as.numeric(NA))
consulta <- safe_fromJSON(url)$result %>% as_tibble()
consulta %>%
select(-date) %>%
mutate_all(~moeda_real(.x)) %>%
mutate(closing = cell_spec(closing, "html", color = "blue")) %>%
kable2()
| opening | closing | lowest | highest | volume | quantity | amount | avg_price |
|---|---|---|---|---|---|---|---|
| R$32.580 | R$32.243,90 | R$32.000 | R$32.780,40 | R$5.636.666,00 | R$174,37 | R$4.582 | R$32.326,16 |
O preço de fechamento foi de R$32.243,90 e suponhamos que tenha sido este o valor pago no dia. (Parece que neste dia o dolar estava em torno de R$4,09)
Para completar esta carteira fictícia vamos adiquirir 0,0032 do valor de um bitcoin
cot_inicio[3] <- consulta$closing
qtd_inicio[3] <- 0.032
Portanto, ao valor de R$32.243,90 compramos 0.032 Bitcoin totalizano 1031.8048 completando nossa carteira.
Semelhante a uma planilha financeira, criaremos uma tabela financeira automatizada que receberá como input os valores da montagem e calculará automaticamente os valores do desmontagem no tempo atual utilizando dados de apis abertas.
“Aquilo que não se pode medir, não se pode melhorar”.Físico irlandês William Thomson
Primeiro é necessário obter os valores mais recentes das cotações das acoes que compramos na bolsa e para isto será necess’rio utilizar outro pacote pois o tidyquant só fornece os dados em frequencia diária.
Utilizaremos portanto, o pacote alphavantager que fornece dados de finanças da API gratuita Alpha Vantage no formato arrumados e também foi desenvolvida pela Business Science (mesmo criados do pacote tidyquant).
Já para a coleta da cotação em tempo real do Bitcoin em reais (R$), utilizaremos novamente a api do mercado bitcoin.
# Importar dados da bolsa de valores ==================================
library(alphavantager) # api para streaming
# consulta_acoes <- map_df(portifolio[1:2], ~{
# alphavantager::av_get(symbol = .x,
# av_fun = "TIME_SERIES_INTRADAY",
# interval = "1min", # "1min", "5min", "15min", "30min" ou "60min"
# outputsize = "compact") %>% # "full"
# bind_cols(stock = rep(.x, nrow(.)))
# }
# )
# saveRDS(consulta_acoes, "consulta_acoes.rds")
consulta_acoes <- readRDS("consulta_acoes.rds")
# Impotar dados do bitcoin ============================================
coin <- "BTC"
method <- "ticker"
url <- glue::glue("https://www.mercadobitcoin.net/api/{coin}/{method}/")
safe_fromJSON <- safely(fromJSON, as.numeric(NA))
consulta_bitcoin <-
safe_fromJSON(url)$result$ticker %>%
as_tibble() %>%
transmute(timestamp = lubridate::ymd_hms(as.POSIXct(date, origin="1970-01-01")),
open, high, low, close = sell, volume = NA, stock = "BTC.BR") %>%
mutate_at(c('open', 'high', 'low', 'close'), ~as.numeric(.x))
# Combinar resultados das consultas ==================================
consulta_atual <-
bind_rows(
consulta_acoes %>%
group_by(stock) %>%
filter(timestamp == last(timestamp)),
consulta_bitcoin
)
# Coleta concluida! ==================================================
Resultados da consulta atual (após combinar a requisição da bolsa de valores e do mercado bitcoin):
consulta_atual %>%
mutate_at(2:4, ~moeda_real(.x)) %>%
mutate(close = cell_spec(moeda_real(close), "html", color = "blue")) %>%
kable2()
| timestamp | open | high | low | close | volume | stock |
|---|---|---|---|---|---|---|
| 2020-03-19 15:54:00 | R$11,32 | R$11,34 | R$11,29 | R$11,34 | 510 | TUPY3.SA |
| 2020-03-19 15:54:00 | R$17,50 | R$17,79 | R$17,42 | R$17,60 | 23120 | ELET3.SA |
| 2020-03-19 21:50:50 | R$27.855,08 | R$33.000,00 | R$27.351,00 | R$32.139,12 | NA | BTC.BR |
Com os valores da Montagem organizados e os valores da Desmontagem coletados em tempo real já podemos contruir nossa tabela financeira automatizada.
A tabela contem:
Aviso: Essa operação de vender o ativo caso o preço da venda seja maior que o da compra é apenas um exemplo! Poderíamos utilizar diversas estatísticas para determinar o momento da operação porém adotei esta apenas para ilustrar o funcionamento da tabela financeira, o limite de opções é a sua criatividade!
Veja a tabela funal com os resultados atualizados em tempo real:
porcentagem <- function(x){paste0(round(x,2), "%")} # Funcao auxiliar
# Tabela resultado
financas <-
tibble(
ativo = portifolio,
cot_inicio = cot_inicio,
qtd_inicio = qtd_inicio,
vol_inicio = cot_inicio * qtd_inicio,
cot_atual = consulta_atual$close,
qtd_atual = qtd_inicio,
vol_atual = cot_atual * qtd_atual,
ganho_perda = vol_atual - vol_inicio,
resultado_bruto = ganho_perda / vol_inicio * 100
) %>%
# Preparar tabela:
mutate(
cot_inicio = moeda_real(cot_inicio),
cot_atual = moeda_real(cot_atual),
vol_inicio = moeda_real(vol_inicio),
vol_atual = moeda_real(vol_atual),
qtd_inicio = round(qtd_inicio,4),
qtd_atual = round(qtd_atual,4),
`Vender?` = ifelse(ganho_perda > 0,"\u2713", "\u2718") ,
cot_atual = cell_spec(cot_atual, "html", color = "blue"),
ganho_perda = cell_spec(moeda_real(ganho_perda), "html",
color = ifelse(ganho_perda > 0,
"green", "red")),
resultado_bruto = cell_spec(porcentagem(resultado_bruto), "html",
color = ifelse(resultado_bruto > 0,
"green", "red"))) %>%
# Exibicao
kable(format = "html", escape = F) %>%
kable_styling(c("striped", "bordered", "hover", "responsive"), full_width = F) %>%
add_header_above(c(" ", "Montagem" = 3,
"Desmontagem / Atual" = 3, "Resultado" = 3))
financas
| ativo | cot_inicio | qtd_inicio | vol_inicio | cot_atual | qtd_atual | vol_atual | ganho_perda | resultado_bruto | Vender? |
|---|---|---|---|---|---|---|---|---|---|
| TUPY3.SA | R$ 39,35 | 190.000 | R$7.476,50 | R$ 11,34 | 190.000 | R$2.154,60 | R$-5.321,90 | -71.18% | ✘ |
| ELET3.SA | R$ 26,05 | 90.000 | R$2.344,50 | R$ 17,60 | 90.000 | R$1.584,00 | R$ -760,50 | -32.44% | ✘ |
| BTC-USD | R$32.243,90 | 0.032 | R$1.031,80 | R$32.139,12 | 0.032 | R$1.028,45 | R$ -3,35 | -0.32% | ✘ |
Agora que já possuímos nossa requisição completa e arrumada em tempo real precisamos ter acesso a esta informação de forma dinâmica também e para isso utilizaremos o bot do telegram.
link me ajudou bastante auns anos atras e agora usei de referencia para este post
library(telegram) # conectar bot telegram
# Definir bot
bot <- TGBot$new(token = bot_token('fgstockbot'))
# Conectar ao R
bot$set_default_chat_id(bot$getUpdates()$message$chat$id[1])
report_stocks <- function(frequencia = 60) {
# load("historico.RData")
# loop infinito
while(
Sys.time() > lubridate::ymd_hm("2020-03-14 10:00") & # abertura
Sys.time() < lubridate::ymd_hm(paste0(Sys.Date(), " 17:00")) # fechamento
) {
# Requisicao das cotacoes atuais
# Acoes
consulta_acoes <- map_df(portifolio[1:2], ~{
cat(paste0("Coletar: ", .x, "...\n"))
av_get(symbol = .x,
av_fun = "TIME_SERIES_INTRADAY",
interval = "1min", # "1min", "5min", "15min", "30min" ou "60min"
outputsize = "compact") %>% # "full"
bind_cols(stock = rep(.x, nrow(.)))
}
)
cat(paste0("Coletar: BTC.BR...\n"))
# Bitcoin
coin = "BTC"
method = "ticker"
url = glue::glue("https://www.mercadobitcoin.net/api/{coin}/{method}/")
safe_fromJSON <- safely(fromJSON, as.numeric(NA))
consulta_bitcoin <-
safe_fromJSON(url)$result$ticker %>%
as_tibble() %>%
transmute(timestamp = lubridate::ymd_hms(as.POSIXct(date, origin="1970-01-01")),
open, high, low, close = sell, volume = NA, stock = "BTC.BR") %>%
mutate_at(c('open', 'high', 'low', 'close'), ~as.numeric(.x))
cat(paste0("Combinar bases...\n"))
# Combinar requisicoes
consulta_atual <-
bind_rows(
consulta_acoes %>%
group_by(stock) %>%
filter(timestamp == last(timestamp))
,
consulta_bitcoin
)
# verifica se a API retornou uma lista
if(!is.null(consulta_atual)) {
cat(paste0("Calcular retornos...\n"))
# Tabela resultado
financas <-
tibble(
ativo = portifolio,
# inicio
cot_inicio = cot_inicio,
qtd_inicio = qtd_inicio,
vol_inicio = cot_inicio * qtd_inicio,
# Desinicio / Atual
cot_atual = consulta_atual$close,
qtd_atual = qtd_inicio,
vol_atual = cot_atual * qtd_atual,
# Resultado
ganho_perda = vol_atual - vol_inicio,
resultado_bruto = ganho_perda / vol_inicio * 100
)
porcentagem <- function(x){paste0(round(x,2), "%")}
# Exibicao
tabela <-
financas %>%
mutate(
cot_inicio = moeda_real(cot_inicio),
cot_atual = moeda_real(cot_atual),
vol_inicio = moeda_real(vol_inicio),
vol_atual = moeda_real(vol_atual),
qtd_inicio = round(qtd_inicio,4),
qtd_atual = round(qtd_atual,4),
# vol_atual = color_bar("lightgreen")(round(vol_atual, 2)),
# vol_inicio = color_bar("lightgreen")(round(vol_inicio, 2)),
`Vender?` = ifelse(ganho_perda > 0,"\u2713", "\u2718") ,
ganho_perda = cell_spec(moeda_real(ganho_perda), "html",
color = ifelse(ganho_perda > 0, "green", "red")),
resultado_bruto = cell_spec(porcentagem(resultado_bruto), "html",
color = ifelse(resultado_bruto > 0, "green", "red"))) %>%
kable(format = "html", escape = F) %>%
kable_styling(c("striped", "bordered", "hover", "responsive"), full_width = F) %>%
add_header_above(c(" ", "Montagem" = 3, "Desmontagem / Atual" = 3, "Resultado" = 3))
save_kable(tabela, file = "table.png", self_contained = F)
cat("Enviando menssagem..\n")
bot$sendPhoto('table.png', caption = paste0("Tabela de resultados - ",Sys.time()))
cat("Menssagem enviada!\n")
}
cat(paste0("Aguarde ", frequencia, " segundos..\n"))
Sys.sleep(frequencia/2)
cat(paste0("Aguarde ", round(frequencia/2,1), " segundos..\n"))
Sys.sleep(frequencia/2)
}
}
Opcções de inovação são inúmeras: